package com.shuyu.web.controller.platform;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.shuyu.common.core.controller.BaseController;
import com.shuyu.common.core.domain.AjaxResult;
import com.shuyu.common.core.domain.Result;
import com.shuyu.common.core.domain.entity.SysUser;
import com.shuyu.common.core.page.TableDataInfo;
import com.shuyu.common.enums.OperationType;
import com.shuyu.common.utils.SecurityUtils;
import com.shuyu.domain.*;
import com.shuyu.service.*;
import com.shuyu.system.service.ISysUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 审批流程相关
 * 
 * @author
 */
@RestController
@RequestMapping("/platform/approval")
@Api(tags = "审批流程管理")
public class PApprovalProcessController extends BaseController
{
    @Resource
    private ApprovalProcessService approvalProcessService;
    @Resource
    private ApprovalProcessNodeService approvalProcessNodeService;
    @Resource
    private ApprovalProcessDetailService approvalProcessDetailService;
    @Resource
    private ApprovalProcessFlowService approvalProcessFlowService;

    @Resource
    private ActivityService activityService;
    @Resource
    private ProductService productService;
    @Resource
    private NFTService nftService;
    @Resource
    private ApprovalAuthorizeService approvalAuthorizeService;
    @Resource
    private ProductTmpService productTmpService;
    @Resource
    private ActivityTmpService activityTmpService;
    @Resource
    private ActivityProductTmpService activityProductTmpService;
    @Resource
    private ActivityCollectCardTmpService activityCollectCardTmpService;
    @Resource
    private ActivityProductService activityProductService;
    @Resource
    private ActivityCollectCardService activityCollectCardService;
    @Resource
    private ISysUserService userService;

    @GetMapping("/test")
    public Result test(Integer id) {
//        nftService.createNFT(id);
        return Result.success();
    }



    @PreAuthorize("@ss.hasPermi('system:approvalProcess:list')")
    @GetMapping("/list")
    @ApiOperation("查询审批流程列表")
    public TableDataInfo list()
    {
        startPage();
        List<ApprovalProcess> list = approvalProcessService.list();
        for (ApprovalProcess approvalProcess : list) {
            List<ApprovalProcessNode> approvalProcessNodeList = approvalProcessNodeService.getList(approvalProcess.getId());
            approvalProcess.setApprovalProcessNodeList(approvalProcessNodeList);
        }
        return getDataTable(list);
    }
    @PreAuthorize("@ss.hasPermi('system:approvalProcess:add')")
    @PostMapping
    @ApiOperation("添加审批流程")
    public AjaxResult add(@RequestBody ApprovalProcess approvalProcess){
        approvalProcessService.save(approvalProcess);
        List<ApprovalProcessNode> approvalProcessNodeList = approvalProcess.getApprovalProcessNodeList();
        for (ApprovalProcessNode approvalProcessNode : approvalProcessNodeList) {
            approvalProcessNode.setProcessId(approvalProcess.getId());
        }
        approvalProcessNodeService.saveBatch(approvalProcessNodeList);
        return AjaxResult.success();
    }
    @PreAuthorize("@ss.hasPermi('system:approvalProcess:update')")
    @PutMapping
    @ApiOperation("修改审批流程")
    public AjaxResult update(@RequestBody ApprovalProcess approvalProcess){
        approvalProcessNodeService.remove(new LambdaQueryWrapper<ApprovalProcessNode>().eq(ApprovalProcessNode::getProcessId,approvalProcess.getId()));
        List<ApprovalProcessNode> approvalProcessNodeList = approvalProcess.getApprovalProcessNodeList();
        for (ApprovalProcessNode approvalProcessNode : approvalProcessNodeList) {
            approvalProcessNode.setProcessId(approvalProcess.getId());
        }
        approvalProcessNodeService.saveBatch(approvalProcessNodeList);
        return toAjax(approvalProcessService.updateById(approvalProcess));
    }

    @PreAuthorize("@ss.hasPermi('system:myApproval:list')")
    @GetMapping("/myApproval")
    @ApiOperation("查询我的审批流程列表")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "startTime", value = "开始时间", dataType = "Date", dataTypeClass = Date.class),
            @ApiImplicitParam(name = "endTime", value = "结束时间", dataType = "Date", dataTypeClass = Date.class),
            @ApiImplicitParam(name = "sourceName", value = "审批名称", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "type", value = "审批类型1产品；2活动； ", dataType = "Integer", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "username", value = "审批发起人", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "auditingStatus", value = "审核状态0待审核 1审核通过 2审核未通过 ", dataType = "Integer", dataTypeClass = Integer.class)

    })
    public TableDataInfo myApproval(String startTime,String endTime, String sourceName, Integer type, String username, Integer auditingStatus)
    {
        long userId = SecurityUtils.getLoginUser().getUserId();
        String nickName = SecurityUtils.getLoginUser().getUser().getNickName();
        List<Long> userIdProductList = new ArrayList<>();
        List<Long> userIdActivityList = new ArrayList<>();
//        userIdList.add(userId);
        //查询是否有授权的审批
        List<ApprovalAuthorize> approvalAuthorizeList = approvalAuthorizeService.list(new LambdaQueryWrapper<ApprovalAuthorize>().eq(ApprovalAuthorize::getAuthorizeUserId, userId).eq(ApprovalAuthorize::getStatus,0).ge(ApprovalAuthorize::getAuthorizeEndTime, new Date()));
        if(CollectionUtil.isNotEmpty(approvalAuthorizeList)){
            for (ApprovalAuthorize approvalAuthorize : approvalAuthorizeList) {
                if(approvalAuthorize.getAuthorizeType()==0){
                    userIdProductList.add(approvalAuthorize.getUserId());
                    userIdActivityList.add(approvalAuthorize.getUserId());
                }else if(approvalAuthorize.getAuthorizeType()==1){
                    userIdProductList.add(approvalAuthorize.getUserId());
                }else if(approvalAuthorize.getAuthorizeType()==2){
                    userIdActivityList.add(approvalAuthorize.getUserId());
                }
            }
        }
        ApprovalAuthorize authorizeProduct = approvalAuthorizeService.getOne(new LambdaQueryWrapper<ApprovalAuthorize>()
                .eq(ApprovalAuthorize::getUserId, userId)
                .and(wrapper->wrapper.eq(ApprovalAuthorize::getAuthorizeType,0).or().eq(ApprovalAuthorize::getAuthorizeType,1))
                .eq(ApprovalAuthorize::getStatus,0).ge(ApprovalAuthorize::getAuthorizeEndTime, new Date())
                .last("limit 1"));
        ApprovalAuthorize authorizeActivity = approvalAuthorizeService.getOne(new LambdaQueryWrapper<ApprovalAuthorize>()
                .eq(ApprovalAuthorize::getUserId, userId)
                .and(wrapper->wrapper.eq(ApprovalAuthorize::getAuthorizeType,0).or().eq(ApprovalAuthorize::getAuthorizeType,2))
                .eq(ApprovalAuthorize::getStatus,0).ge(ApprovalAuthorize::getAuthorizeEndTime, new Date())
                .last("limit 1"));

        startPage();
        List<ApprovalProcessDetail> approvalProcessDetailList = approvalProcessDetailService.getList(userIdProductList, userIdActivityList, userId, startTime, endTime, sourceName, type, username, auditingStatus);
        for (ApprovalProcessDetail approvalProcessDetail : approvalProcessDetailList) {
            List<ApprovalProcessFlow> list = approvalProcessFlowService.getList(approvalProcessDetail.getId());
            int detailType = approvalProcessDetail.getType();
            ApprovalAuthorize authorize;
            List<Long> userIdList;
            if(detailType==1){
                authorize =  authorizeProduct;
                userIdList = userIdProductList;
            }else {
                authorize = authorizeActivity;
                userIdList = userIdActivityList;
            }
            //处理授权
            for (ApprovalProcessFlow approvalProcessFlow : list) {
                if(approvalProcessFlow.getProcessIndex()==0){
                    continue;
                }
                if(approvalProcessFlow.getAuditingStatus()!=0){
                    continue;
                }
                Long uId = approvalProcessFlow.getUserId();
                if(uId != userId){//判断流程节点为其他账号的时候，是否有被授权给当前账号
                    if(userIdList.contains(uId)){
                        approvalProcessFlow.setAuthorizationUserId(userId);
                        approvalProcessFlow.setAuthorizationUsername(nickName);
                    }
                }else {//判断流程节点为当前账号的时候，是否有被授权给其他账号
                    if(authorize != null){
                        Long authorizeUserId = authorize.getAuthorizeUserId();
                        SysUser sysUser = userService.selectUserById(authorizeUserId);
                        approvalProcessFlow.setAuthorizationUserId(authorizeUserId);
                        approvalProcessFlow.setAuthorizationUsername(sysUser.getNickName());
                    }
                }

            }

            approvalProcessDetail.setFlowList(list);
            if(approvalProcessDetail.getAuditingStatus()==0){
                if(userId==approvalProcessDetail.getAuditingUserId()){
                    if(authorize != null){
                        approvalProcessDetail.setAllowApproval(0);
                    }else {
                        approvalProcessDetail.setAllowApproval(1);
                    }
                }else {
                    if(userIdList.contains(approvalProcessDetail.getAuditingUserId())){
                        approvalProcessDetail.setAllowApproval(1);
                    }else{
                        approvalProcessDetail.setAllowApproval(0);
                    }
                }
            }else {
                approvalProcessDetail.setAllowApproval(0);
            }

        }
        return getDataTable(approvalProcessDetailList);
    }
    @PreAuthorize("@ss.hasPermi('system:myApproval:approval')")
    @PutMapping("/myApproval/approval")
    @ApiOperation("审批提交流程")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "auditingRemark", value = "审核说明", dataType = "String", dataTypeClass = String.class),
            @ApiImplicitParam(name = "detailId", value = "审批流程详情ID", dataType = "Integer", dataTypeClass = Integer.class),
            @ApiImplicitParam(name = "auditingStatus", value = "审核状态 1审核通过 2审核未通过", dataType = "Integer", dataTypeClass = Integer.class)
    })
    public AjaxResult approvalMyApproval(@RequestBody Map<String,Object> params)
    {
        String auditingRemark = (String) params.get("auditingRemark");
        int detailId = (int)params.get("detailId");
        int auditingStatus = (int)params.get("auditingStatus");
        Long userId = SecurityUtils.getLoginUser().getUserId();
        ApprovalProcessDetail approvalProcessDetail = new ApprovalProcessDetail();
        approvalProcessDetail.setId(detailId);


        ApprovalProcessFlow approvalProcessFlow = approvalProcessFlowService.getOne(new LambdaQueryWrapper<ApprovalProcessFlow>()
                .eq(ApprovalProcessFlow::getDetailId, detailId).eq(ApprovalProcessFlow::getAuditingStatus, 0)
                .orderByAsc(ApprovalProcessFlow::getProcessIndex).last("limit 1"));
        //判断是否是授权审核的
        if(approvalProcessFlow.getUserId() != userId){
            approvalProcessFlow.setAuthorizationUserId(userId);
            String nickName = SecurityUtils.getLoginUser().getUser().getNickName();
            approvalProcessFlow.setAuthorizationUsername(nickName);
        }
        approvalProcessFlow.setAuditingRemark(auditingRemark);
        approvalProcessFlow.setAuditingStatus(auditingStatus);
        approvalProcessFlow.setAuditingTime(new Date());
        approvalProcessFlowService.updateById(approvalProcessFlow);
        if(auditingStatus==2){
            approvalProcessDetail.setRejectUserId(userId);
            approvalProcessDetail.setAuditingStatus(auditingStatus);
            approvalProcessDetail.setRejectReason(auditingRemark);
            updateAuditStatus(detailId, auditingStatus,auditingRemark);
        }else if(auditingStatus==1){
            int count = approvalProcessFlowService.count(new LambdaUpdateWrapper<ApprovalProcessFlow>()
                    .eq(ApprovalProcessFlow::getDetailId, detailId).eq(ApprovalProcessFlow::getAuditingStatus, 1));
            int count1 = approvalProcessFlowService.count(new LambdaUpdateWrapper<ApprovalProcessFlow>()
                    .eq(ApprovalProcessFlow::getDetailId, detailId));
            if(count1==count){//审核通过数量跟流程数量一样多 说明流程全部审核完成
                approvalProcessDetail.setAuditingStatus(auditingStatus);
                updateAuditStatus(detailId, auditingStatus,"审核通过");
            }else{
                ApprovalProcessFlow processFlow = approvalProcessFlowService.getOne(new LambdaUpdateWrapper<ApprovalProcessFlow>()
                        .eq(ApprovalProcessFlow::getDetailId, detailId).eq(ApprovalProcessFlow::getAuditingStatus, 0)
                        .orderByAsc(ApprovalProcessFlow::getProcessIndex).last("limit 1"));
                approvalProcessDetail.setAuditingUserId(processFlow.getUserId());
            }
        }
        approvalProcessDetail.setModifyTime(new Date());
        boolean update = approvalProcessDetailService.updateById(approvalProcessDetail);
        return toAjax(update);
    }

    private void updateAuditStatus(int detailId,int auditingStatus,String auditingRemark){
        ApprovalProcessDetail detail = approvalProcessDetailService.getById(detailId);
        //审批类型1产品；2活动
        if(detail.getType()==1){
            handleProduct(detail, auditingStatus, auditingRemark);
        }else {
            handleActivity(detail, auditingStatus);
        }
    }
    private void handleProduct(ApprovalProcessDetail detail,int auditingStatus,String auditingRemark){
        Integer operationType = detail.getOperationType();
        Integer productId = detail.getSourceId();
        Product product = new Product();
        if(auditingStatus==1){
            if(operationType == OperationType.修改.type){
                ProductTmp productTmp = productTmpService.getOne(new LambdaQueryWrapper<ProductTmp>().eq(ProductTmp::getPId, productId).last("limit 1"));
                product.setName(productTmp.getName());
                product.setType(productTmp.getType());
                product.setPrice(productTmp.getPrice());
                product.setStock(productTmp.getStock());
                product.setIntroduction(productTmp.getIntroduction());
                product.setImg(productTmp.getImg());
                product.setAlbum(productTmp.getAlbum());
                product.setSource(productTmp.getSource());
                product.setEquityEndTime(productTmp.getEquityEndTime());
                product.setStatus(0);
            }else if(operationType == OperationType.上架.type){
                Product product1 = productService.getById(detail.getSourceId());
                if(product1.getType()==1){
//                    nftService.createNFT(product1.getId());
                    product.setNftCreateTaskStatus(1);
                }
                product.setStatus(0);
            }else if(operationType == OperationType.删除.type){
                product.setStatus(1);
                product.setDelFlag(1);
            }else if(operationType == OperationType.下架.type){
                product.setStatus(1);
            }
        }
        if(operationType == OperationType.修改.type){
            productTmpService.remove(new LambdaQueryWrapper<ProductTmp>().eq(ProductTmp::getPId,productId));
        }
        product.setAuditRemark(auditingRemark);
        product.setId(detail.getSourceId());
        product.setAuditStatus(auditingStatus);
        productService.updateById(product);
    }
    private void handleActivity(ApprovalProcessDetail detail,int auditingStatus){
        Integer operationType = detail.getOperationType();
        Integer activityId = detail.getSourceId();
        Activity activity = new Activity();
        if(auditingStatus==1){
            if(operationType == OperationType.修改.type){
                ActivityTmp activityTmp = activityTmpService.getOne(new LambdaQueryWrapper<ActivityTmp>().eq(ActivityTmp::getAId, activityId).last("limit 1"));
                activity.setName(activityTmp.getName());
                activity.setIntroduction(activityTmp.getIntroduction());
                activity.setType(activityTmp.getType());
                activity.setStartTime(activityTmp.getStartTime());
                activity.setEndTime(activityTmp.getEndTime());
                activity.setStatus(0);
                addActivityList(activityTmp);
            }else if(operationType == OperationType.删除.type){
                activity.setDelFlag(1);
                activity.setStatus(1);
            }else if(operationType == OperationType.上架.type){
                activity.setStatus(0);
            }else if(operationType == OperationType.下架.type){
                activity.setStatus(1);
            }
        }
        if(operationType == OperationType.修改.type){
            delActivityTmp(activityId);
        }
        activity.setId(activityId);
        activity.setAuditStatus(auditingStatus);
        activityService.updateById(activity);
    }
    private void  addActivityList(ActivityTmp activityTmp){
        List<ActivityProductTmp> activityProductTmpList = activityProductTmpService.list(new LambdaQueryWrapper<ActivityProductTmp>()
                .eq(ActivityProductTmp::getActivityId, activityTmp.getId()));
        activityProductService.remove(new LambdaUpdateWrapper<ActivityProduct>().eq(ActivityProduct::getActivityId,activityTmp.getAId()));
        for (ActivityProductTmp activityProductTmp : activityProductTmpList) {
            ActivityProduct activityProduct = new ActivityProduct(activityTmp.getAId(), activityProductTmp.getActivityType(), activityProductTmp.getProductId(),
                    activityProductTmp.getStartTime(), activityProductTmp.getEndTime(), activityProductTmp.getDiscountStatus(), activityProductTmp.getDiscount(),
                    activityProductTmp.getPoint(), activityProductTmp.getRate(), activityProductTmp.getCreateTime());
            activityProductService.save(activityProduct);
            if(activityTmp.getType()==1){// 1：集卡消卡；
                List<ActivityCollectCardTmp> activityCollectCardTmpList = activityCollectCardTmpService.list(new LambdaQueryWrapper<ActivityCollectCardTmp>()
                        .eq(ActivityCollectCardTmp::getActivityProductId,activityProductTmp.getId()));
                activityCollectCardService.remove(new LambdaUpdateWrapper<ActivityCollectCard>()
                        .eq(ActivityCollectCard::getActivityProductId,activityProduct.getId()));
                List<ActivityCollectCard> activityCollectCardList = new ArrayList<>();
                for (ActivityCollectCardTmp activityCollectCardTmp : activityCollectCardTmpList) {
                    ActivityCollectCard activityCollectCard = new ActivityCollectCard(activityProduct.getId(), activityCollectCardTmp.getProductId());
                    activityCollectCardList.add(activityCollectCard);
                }
                activityCollectCardService.saveBatch(activityCollectCardList);
            }
        }

    }
    private void delActivityTmp(int activityId){
        activityTmpService.remove(new LambdaQueryWrapper<ActivityTmp>().eq(ActivityTmp::getAId,activityId));
        activityProductTmpService.remove(new LambdaQueryWrapper<ActivityProductTmp>().eq(ActivityProductTmp::getAId, activityId));
        activityCollectCardTmpService.remove(new LambdaUpdateWrapper<ActivityCollectCardTmp>().eq(ActivityCollectCardTmp::getAId,activityId));

    }
}
